# -*- coding: utf-8 -*-
# @Date    : 2017-04-25 14:13:35
# @Author  : fancy (fancy@thecover.co)
import re
from hashlib import md5
from PIL import Image
from datetime import datetime

from flask import request, render_template, redirect, url_for, session
from flask_mail import Message
from itsdangerous import URLSafeTimedSerializer, BadTimeSignature
from flask_login import login_user, logout_user, login_required, \
    current_user

from app import app, db, mail, cache
from .models import User
from ..utils import generate_captcha


ts = URLSafeTimedSerializer(app.config["SECRET_KEY"])
username_p = re.compile(r'[^\w]')


@app.route('/signin', methods=['GET', 'POST'])
def login():
    if request.method == 'GET':
        return render_template('log.html', disable_right=False)
    elif request.method == 'POST':
        form = request.form
        user = User.query.filter_by(name=form.get('username')).first()
        if not user or (not user.verify_password(form.get('password'))):
            msg = u'用户名或密码不正确'
            return render_template(
                'log.html', disable_right=False, message=msg)
        user.last_login = datetime.now()
        db.session.commit()
        login_user(user)
        next = form.get('next', url_for('index'))
        return redirect(next)


@app.route('/signout', methods=['GET'])
def signout():
    logout_user()
    return render_template('log.html', logout=True)


@app.route('/member/<string:username>', methods=['GET'])
@login_required
def user_index(username):
    cache.set('purple', 'sb', timeout=30)
    return render_template('user.html')


@app.route('/settings/avatar', methods=['GET', 'POST'])
@login_required
def set_avatar():
    if request.method == 'POST':
        up_file = request.files['avatar']
        imgs = ['jpg', 'jpeg', 'gif', 'png']
        if up_file.content_type.split('/')[1] not in imgs:
            return render_template('set_avatar.html', message=u'图片格式不正确')
        up_file.read(app.config['AVATAR_MAX_SIZE'])
        if up_file.read(5):
            return render_template('set_avatar.html', message=u'图片不能大于2M')
        im = Image.open(up_file)
        avatar_large = im.resize((73, 73))
        avatar_normal = im.resize((48, 48))
        avatar_small = im.resize((24, 24))
        large_name = '/static/img/gravatar/%s' % md5(avatar_large.tobytes()).hexdigest()
        normal_name = '/static/img/gravatar/%s' % md5(avatar_normal.tobytes()).hexdigest()
        small_name = '/static/img/gravatar/%s' % md5(avatar_small.tobytes()).hexdigest()
        avatar_large.save('app%s' % large_name, 'png')
        avatar_normal.save('app%s' % normal_name, 'png')
        avatar_small.save('app%s' % small_name, 'png')
        current_user.avatar = normal_name
        current_user.avatar_large = large_name
        current_user.avatar_small = small_name
        db.session.commit()
    return render_template('set_avatar.html')


@app.route('/settings', methods=['POST'])
@login_required
def user_settings():
    current_user.email = request.form.get('email')
    current_user.website = request.form.get('website')
    current_user.location = request.form.get('location')
    current_user.signature = request.form.get('signature')
    current_user.brief = request.form.get('brief')
    db.session.commit()
    message = u'修改成功'
    return render_template('user.html', message=message)


def send_verify_email(email):
    token = ts.dumps(email)
    msg = Message(u'V2EX 邮箱验证', recipients=[email])
    confirm_url = '%s%s' % (
        app.config['HOST'], url_for('account_confirm', token=token))
    msg.body = u'V2EX 邮箱验证,请点击%s验证' % confirm_url
    mail.send(msg)


@app.route('/signup', methods=['GET', 'POST'])
def user_signup():
    if request.method == 'GET':
        code, captcha_img = generate_captcha()
        session['code'] = code
        return render_template('signup.html', captcha_img=captcha_img)
    elif request.method == 'POST':
        captcha_code = request.form.get('captcha_code')
        username = request.form.get('username')
        email = request.form.get('email')
        errs = []
        if not username or username_p.search(username):
            errs.append(u'用户名只能使用大小写英文字母和数字 a-Z 0-9')
        else:
            user = User.query.filter_by(name=username).count()
            if user > 0:
                errs.append(u'该用户名已存在')
        if captcha_code != session['code']:
            errs.append(u'验证码错误')
        if not email or '@' not in email:
            errs.append(u'请输入合法邮箱地址')
        else:
            user = User.query.filter_by(email=email).count()
            if user > 0:
                errs.append(u'该邮箱地址已注册')
        if not errs:
            try:
                send_verify_email(email)
            except Exception as e:
                errs.append(u'请输入合法邮箱地址')
        if errs:
            code, captcha_img = generate_captcha()
            session['code'] = code
            return render_template(
                'signup.html', username=username,
                email=email, captcha_img=captcha_img, errs=errs)
        password = request.form.get('password')
        user = User(username, email, password)
        db.session.add(user)
        db.session.commit()
        return render_template('log.html', register=True)


@app.route('/account/confirm/<token>', methods=['GET'])
def account_confirm(token):
    try:
        email = ts.loads(token, max_age=7200)
    except BadTimeSignature:
        email = ts.loads(token)
        send_verify_email(email)
        message = u'链接已过期,已重新发送验证链接'
        return render_template('info_page.html', message=message)
    user = User.query.filter_by(email=email).first_or_404()
    user.active = 0
    db.session.commit()
    return redirect(url_for('login'))


@app.route('/account/forgetPassword', methods=['GET', 'POST'])
def forget_password():
    return render_template('forget_password.html')


@app.route('/account/changePassword', methods=['POST'])
def change_password():
    email = request.form.get('email')
    user = User.query.filter_by(email=email).count()
    if not user:
        return u'邮箱未注册'
    if not cache.has(email):
        cache.set(email, None, 60)
    else:
        return u'请稍等'
    send_verify_email(email)
    return 'success'
